package cn.iocoder.yudao.module.ems.service.spares;

import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.module.ems.controller.admin.eqtype.vo.EqTypeListReqVO;
import cn.iocoder.yudao.module.ems.dal.dataobject.classification.ClassificationDO;
import cn.iocoder.yudao.module.ems.dal.dataobject.eqtype.EqTypeDO;
import cn.iocoder.yudao.module.ems.service.classification.ClassificationService;
import com.google.common.annotations.VisibleForTesting;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;

import java.util.*;
import cn.iocoder.yudao.module.ems.controller.admin.spares.vo.*;
import cn.iocoder.yudao.module.ems.dal.dataobject.spares.SparesDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;

import cn.iocoder.yudao.module.ems.convert.spares.SparesConvert;
import cn.iocoder.yudao.module.ems.dal.mysql.spares.SparesMapper;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
import static cn.iocoder.yudao.module.ems.enums.ErrorCodeConstants.*;

/**
 * 备品备件 Service 实现类
 *
 * @author dason
 */
@Service
@Validated
public class SparesServiceImpl implements SparesService {

    @Resource
    private SparesMapper sparesMapper;

    @Resource
    private ClassificationService classificationService;

    /**
     * 获得分类条件：查询指定分类的子分类编号们，包括自身
     * @param classificationId 分类编号
     * @return 分类编号集合
     */
    private Set<Long> getClassificationCondition(Long classificationId) {
        if (classificationId == null) {
            return Collections.emptySet();
        }
        Set<Long> classificationIds = convertSet(classificationService.getClassificationsByParentIdFromCache(
                classificationId, true), ClassificationDO::getId);
        classificationIds.add(classificationId); // 包括自身
        return classificationIds;
    }

    @Override
    public Long createSpares(SparesCreateReqVO reqVO) {
        // 校验正确性
        checkCreateOrUpdate(null, reqVO.getItemNo(), reqVO.getLowerLimit(), reqVO.getUpperLimit());
        // 插入
        SparesDO spares = SparesConvert.INSTANCE.convert(reqVO);
        sparesMapper.insert(spares);
        // 返回
        return spares.getId();
    }

    @Override
    public void updateSpares(SparesUpdateReqVO reqVO) {
        // 校验正确性
        checkCreateOrUpdate(reqVO.getId(), reqVO.getItemNo(), reqVO.getLowerLimit(), reqVO.getUpperLimit());
        // 更新
        SparesDO updateObj = SparesConvert.INSTANCE.convert(reqVO);
        sparesMapper.updateById(updateObj);
    }

    @Override
    public void deleteSpares(Long id) {
        // 校验存在
        this.validateSparesExists(id);
        // 删除
        sparesMapper.deleteById(id);
    }

    private void validateSparesExists(Long id) {
        if (sparesMapper.selectById(id) == null) {
            throw exception(SPARES_NOT_EXISTS);
        }
    }

    @Override
    public SparesDO getSpares(Long id) {
        return sparesMapper.selectById(id);
    }

    @Override
    public List<SparesDO> getSparesList(Collection<Long> ids) {
        return sparesMapper.selectBatchIds(ids);
    }

    @Override
    public PageResult<SparesDO> getSparesPage(SparesPageReqVO reqVO) {
        return sparesMapper.selectPage(reqVO, getClassificationCondition(reqVO.getClassificationId()));
    }

    @Override
    public List<SparesDO> getSparesList(SparesExportReqVO exportReqVO) {
        return sparesMapper.selectList(exportReqVO);
    }

    private void checkCreateOrUpdate(Long id, String itemNo, Integer lowerLimit, Integer upperLimit) {
        // 校验物料编号唯一
        checkItemNoUnique(id, itemNo);
        // 校验上限比下限大
        if(lowerLimit != null && upperLimit != null && lowerLimit > upperLimit) {
            throw exception(LOWER_lIMIT_HIGHER);
        }
    }

    @VisibleForTesting
    public void checkItemNoUnique(Long id, String itemNo) {
        if (StrUtil.isBlank(itemNo)) {
            return;
        }
        SparesDO spares = sparesMapper.selectByItemNo(itemNo);
        if (spares == null) {
            return;
        }
        // 如果 id 为空，说明不用比较是否为相同 id 的备品备件
        if (id == null) {
            throw exception(SPARES_ITEMNO_EXISTS);
        }
        if (!spares.getId().equals(id)) {
            throw exception(SPARES_ITEMNO_EXISTS);
        }
    }

    @Override
    public List<SparesDO> getSimpleSpares(SparesListReqVO reqVO) {
        return sparesMapper.selectList(reqVO);
    }

}
